import Vue from 'vue'
import Vuex from 'vuex'

// Vue.js 插件
Vue.use(Vuex)

//引入接口配置
import { getMenuApi, getUserInfoApi } from '@/api/layout/index.js'
//引入工具函数
import utils from '@/utils/utils.js'

//初始化本地储存数据
const useTabsMode = window.localStorage.getItem('useMTabsMode')==0? 0:1
const useMultiLevelMenu = window.localStorage.getItem('useMultiLevelMenu')==0? 0:1


//读取用户信息
const userInfoStr = window.localStorage.getItem('userInfo')
const userInfo = strToJson(userInfoStr)

const state = {
    isCollapse: false,//左侧菜单是否折叠
    menuOrigin: [],//原始菜单格式（二维）
    menuOriginHasChildren: [],//原始菜单包含children属性
    menuIsReady: false,//菜单权限已经完成加载

    userInfo: userInfo,//用户信息

    changePswDialogVisible: false,//修改密码弹窗状态
    useTabsMode: useTabsMode,//多tab模式
    useMultiLevelMenu: useMultiLevelMenu,//多级菜单模式
    tabs: [
        {
            path: "/dashboard",
            title: "首页",
            name: "dashboard",
            closable: false,//是否可以关闭
            showContextmenu: false,//右键菜单展示状态
        }
    ],//标签列表
}

const getters = {
    
}
//Vuex中store数据改变的唯一方法就是mutation
const mutations = {
    //折叠开关切换
    isCollapseToggle(state){
        state.isCollapse = !state.isCollapse
    },
    //更新原始菜单
    updateMenuOrigin(state,data = []){
        //保存数据
        state.menuOrigin = data
    },
    //更新路由注册完成状态
    updateMenuStatus(state,status){
        state.menuIsReady = status
    },
    //关闭或者开启密码弹窗
    toggleChangePswDialog(state, status){
        state.changePswDialogVisible = status
    },
    //更新多tab模式的状态
    toggleUseTabsMode(state, status){
        state.useTabsMode = status
        //更新本地存储
        window.localStorage.setItem('useMTabsMode', status)
    },
    //更新多级菜单模式的状态
    toggleUseMultiLevelMenu(state, status){
        state.useMultiLevelMenu = status
        //更新本地存储
        window.localStorage.setItem('useMultiLevelMenu', status)
    },
    //添加标签
    addTab(state, tab){
        state.tabs.push(tab)
    },
    //移除单个标签
    removeTab(state, index){
        state.tabs.splice(index, 1)
    },
    //清空标签
    clearTab(){
        //只保留第一个
        state.tabs = [state.tabs[0]]
    },

    //通用修改方法
    commonUpdateState(state, option = {}){
        state[option.key] = option.value
    }
}

// mutations的再封装，mutations本身只负责state的数据修改，其余逻辑放在actions中，在通过它进行一系列逻辑处理之后再调用mutations
const actions = {
    //菜单初始化
    async menuInit({dispatch, commit,state}, vm){
        //更新标识
        commit('updateMenuStatus', true)
        //获取菜单列表
        await dispatch('getMenuList')
        //根据长度判断是否获取成功
        if(state.menuOrigin.length > 0){
            //注册异步路由
            dispatch('addRoutes', vm) 
        }else{
            //更新标识
            commit('updateMenuStatus', false)
        }
        //注册 Not_found 路由
        vm.$router.addRoute({
            path: '*',
            name: 'Not_found',
            component: () => import('@/views/404.vue')
        })
    },
    //获取菜单列表
    async getMenuList({commit, state}){
        try {
            const result = await getMenuApi()
            //处理返回
            if(result.code == 1){
                //深拷贝一份
                const data = utils.deepCopy(result.data)
                //保存菜单数据
                commit('updateMenuOrigin', data)
                //为节点挂载children属性
                utils.buildTree(result.data)
                //保存菜单数据
                commit('commonUpdateState', {
                    key: "menuOriginHasChildren", value: result.data
                })
            }
        } catch (error) {
            console.log('error',error)
        }
    },
    //获取用户信息
    async getUserInfo({commit, state}){
        try {
            const result = await getUserInfoApi()
            //处理返回
            if(result.code == 1){
                //保存用户数据
                commit('commonUpdateState', {
                    key: "userInfo", value: result.data || {}
                })
                //保存用户信息
                window.localStorage.setItem('userInfo', JSON.stringify(result.data))
            }
        } catch (error) {
            console.log('error',error)
        }
    },
    //注册异步路由
    addRoutes({dispatch, commit, state}, vm) {
        //遍及菜单节点
        for (let i = 0; i < state.menuOrigin.length; i++) {
            let item = state.menuOrigin[i]

            //是否是真实页面
            var isPage = judgePathIsTruePage(item)
            //不是真实页面不注册
            if(!isPage){
                continue
            }
            //判断是否是全屏页面
            if (item.isFull == 1) {
                //一级路由
                vm.$router.addRoute({
                    path: item.path,
                    name: item.name || item.path,
                    component: () => import(`@/views${item.path}.vue`)
                })
            } else {
                //嵌套路由

                //模块是否已经中注册
                var parentName = 'layout-' + item.path.split('/').slice(1)[0]
                var allRoutes = vm.$router.getRoutes()
                var hasRegister = allRoutes.some(item => {
                    return item.name == parentName
                })
                //先注册一级路由，再注册嵌套路由
                if (!hasRegister) {
                    vm.$router.addRoute({
                        path: '/' + parentName,
                        name: parentName,
                        component: () => import('@/layout/index.vue')
                    })
                }
                //注册二级路由
                vm.$router.addRoute(parentName, {
                    name: item.name || item.path,
                    path: item.path,
                    component: () => import(`@/views${item.path}.vue`)
                })
            }
        }

        //console.log('所有路由',vm.$router.getRoutes())
    },
}

//将字符串转换为对象
function strToJson(str){
    try {
        return JSON.parse(str)
    } catch (error) {
        return {}
    }
}

//是否是真实页面
function judgePathIsTruePage(item){
    //忽略白名单
    const whiteList = ["/", "/logon", "/dashboard"]
    if (whiteList.includes(item.path)) {
        return false
    }
    //忽略不是菜单的页面
    if(item.isMenu != 1){
        return false
    }
    //路径层次
    const pathLevel = item.path.split('/').slice(1)
    //超过2层才算真实页面
    return pathLevel.length >= 2? true:false
}

export default new Vuex.Store({
    state,// 状态对象，相当于data
    getters,// 包含多个getter计算属性函数的对象
    mutations, // mutations 里面装着改变数据的方法集合，处理数据逻辑的方法全部放在 mutations 里，使数据和视图分离。
    actions // action 可以包含任意异步操作，例如发送ajax请求
})